<?php
/**
 * Config support
 *
 * @category Core
 * @package  Core_Acl
 *
 * @version $Id: Acl.php 87 2010-08-29 10:15:50Z vadim.leontiev $
 */

class Core_Acl extends Zend_Acl
{

    /**
     * Constructor
     *
     * @param Zend_Config $config
     */
    public function  __construct(Array $config)
    {
        $this->_build($config);
    }

    /**
     * Add rules to Acl
     *
     * @param array|Zend_Config $config
     */
    protected function _build(Array $config)
    {
        if (isset($config['roles'])) {
            $this->_addRoles($config['roles']);
        }

        if (isset($config['resources'])) {
            $this->_addResources($config['resources']);
        }

        if (isset($config['rules'])) {
            $this->_addRules($config['rules']);
        }

        return $this;
    }

    /**
     * Add roles
     *
     * @param array $roles
     */
    protected function _addRoles($roles)
    {
        foreach ($roles as $name => $parent) {
            if (!$this->hasRole($name)) {
                if (empty($parent)) {
                    $parent = null;
                }
                $this->addRole(new Zend_Acl_Role($name), $parent);
            }
        }
        return $this;
    }

    /**
     * Add resources
     *
     * @param array $resources
     */
    protected function _addResources($resources)
    {
        foreach ($resources as $resource => $parent) {
            if (empty($parent)) {
                $parent = null;
            }

            if (!$this->has($resource)) {
                $this->add(new Zend_Acl_Resource($resource), $parent);
            }
        }
        return $this;
    }

    /**
     * Add new rules to registry
     * Add administrator role, is allowed all privileges
     *
     * @param   array $rules
     * @return  Core_Acl  $this
     */
    protected function _addRules($rules)
    {
        foreach ($rules as $options) {
            $this->_addRule($options);
        }

        $this->allow('administrator');

        return $this;
    }


    /**
     * _addRule
     *
     * add new rule to registry
     *
     * @param   string $type allow|deny
     * @param   array $options
     * @return  Core_Acl  $this
     */
    protected function _addRule($options)
    {
        if (isset($options['resource'])) {
            if (isset($options['action']) && !empty($options['action'])) {
                $action = $options['action'];
            } else {
                // for all actions
                $action = null;
            }

            if (isset($options['role'])&&!empty($options['role'])) {
                $role = $options['role'];
            } else {
                // for all roles
                $role = null;
            }

            if ($this->has($options['resource'])) {
                $this->{$options['rule']}($role,
                               $options['resource'],
                               $action);
            }
        }
        return $this;
    }
}